package am.NotenProgramm.IO;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;

import am.NotenProgramm.objects.*;

public class DataStream {

	// the directory where the files should be saved
	public String dir = "data";

	/*
	 * Load/Save Profile
	 */
	public void saveProfile(Profile profile) {
		checkDir(dir);
		// Get the Subjects from the Profile and Save them
		Subject[] subjects = profile.getSubjects();
		try {
			FileWriter fstream = new FileWriter(dir + "/" + checkSymbols(profile.getName())
					+ ".profile");
			BufferedWriter out = new BufferedWriter(fstream);
			// write the Profile Data (no Subjects)
			out.write(profile.getString() + "<:>");
			out.newLine();
			for (int i = 0; i < subjects.length; i++) {
				// Save the list of all Subjects
				out.write(checkSymbols(subjects[i].getName()) + "<:>");
				out.newLine();
				// Save the Subjects in seperate files
				saveSubject(subjects[i], checkSymbols(profile.getName()));
			}
			out.close();
		} catch (Exception e) {
			System.err.println("Error: " + e.getMessage());
		}
	}

	public Profile loadProfile(String profileName) {
		checkDir(dir);
		File file = new File(dir + "/"
				+ checkSymbols(profileName) + ".profile");
		File file2 = new File(dir + "/"
				+ checkSymbols(profileName));
		if (!file.exists()) {
			saveProfile(new Profile(profileName, new Subject[0]));
			file2.mkdir();
		}
		// Load the whole file
		StringBuilder contents = new StringBuilder();
		try {
			BufferedReader input = new BufferedReader(new FileReader(dir + "/"
					+ checkSymbols(profileName) + ".profile"));
			try {
				String line = null;
				while ((line = input.readLine()) != null) {
					contents.append(line);
				}
			} finally {
				input.close();
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		String loadedProfile = contents.toString();
		// Split the files at the tag
		String[] subjectStrings = loadedProfile.split("<:>");
		/*
		 * Create a subject for each entry in the profile and load them into an
		 * array. They are loaded via loadSubject
		 */
		Subject[] subjects = new Subject[subjectStrings.length - 1];
		String stringToFeed = "";
		int j = 0;
		for (int i = 0; i < subjectStrings.length; i++) {
			// filter the profile data from the subjects and load both
			// they will be used to generate the profile data
			if (!subjectStrings[i].startsWith("profileData=")) {
				subjects[j] = loadSubject(subjectStrings[i], profileName);
				j++;
			} else {
				stringToFeed = subjectStrings[i].substring(12);
			}

		}
		Profile profile = new Profile(profileName, stringToFeed, subjects);
		return profile;
	}

	/*
	 * Load/Save Subjects
	 */
	public void saveSubject(Subject subject, String profileName) {
		checkDir(dir + "/" + profileName);
		// get the grades from the subject
		Grade[] myGrades = subject.getGrades();
		try {
			FileWriter fstream = new FileWriter(dir + "/" + profileName + "/" + checkSymbols(subject.getName())
					+ ".fach");
			BufferedWriter out = new BufferedWriter(fstream);
			// write the Subject data (not the grades)
			out.write(subject.getString());
			out.newLine();
			// write the grades with the autogenerated String
			for (int i = 0; i < myGrades.length; i++) {
				out.write(myGrades[i].toString());
				out.newLine();
			}
			out.close();
		} catch (Exception e) {
			System.err.println("Error: " + e.getMessage());
		}
	}

	public Subject loadSubject(String subjectName, String profileName) {
		checkDir(dir + "/" + checkSymbols(profileName));
		// load the whole file
		StringBuilder contents = new StringBuilder();
		try {
			BufferedReader input = new BufferedReader(new FileReader(dir + "/" + checkSymbols(profileName) + "/"
					+ checkSymbols(subjectName) + ".fach"));
			try {
				String line = null;
				while ((line = input.readLine()) != null) {
					contents.append(line);
				}
			} finally {
				input.close();
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		String loadedFile = contents.toString();
		// first split at the marks
		String[] gradeStrings = loadedFile.split("<grade>");
		Grade[] grades = new Grade[gradeStrings.length - 1];
		String stringToFeed = "";
		int j = 0;
		for (int i = 0; i < gradeStrings.length; i++) {
			// filter the subject data from the grades and load both
			// they will be used to generate the subject data
			if (!gradeStrings[i].startsWith("subjectData=")) {
				grades[j] = new Grade(gradeStrings[i]);
				j++;
			} else {
				stringToFeed = gradeStrings[i].substring(12);
			}
		}
		// create the subject with the loaded data
		Subject subject = new Subject(subjectName, grades, stringToFeed);
		return subject;
	}

	/*
	 * Load/Save Settings
	 */
	public void saveSettings(SettingsData settings) {
		checkDir(dir);
		// just write the autogenerated String into the file
		try {
			FileWriter fstream = new FileWriter(dir + "/Settings.config");
			BufferedWriter out = new BufferedWriter(fstream);
			out.write(settings.toString());
			out.close();
		} catch (Exception e) {
			System.err.println("Error: " + e.getMessage());
		}
	}

	public SettingsData loadSettings() {
		checkDir(dir);
		// load the whole file into a String
		StringBuilder contents = new StringBuilder();
		try {
			BufferedReader input = new BufferedReader(new FileReader(dir
					+ "/Settings.config"));
			try {
				String line = null;
				while ((line = input.readLine()) != null) {
					contents.append(line);
				}
			} finally {
				input.close();
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		String loadedSettings = contents.toString();
		// generate the SettingsData from the String
		// data will be generated in the constructor
		return new SettingsData(loadedSettings);
	}

	// Check the directory where the files are located
	public void checkDir(String directory) {
		File file = new File(directory);
		if (!file.exists()) {
			if (file.mkdir()) {
				System.out.println("Directory is created!");
			} else {
				System.out.println("Failed to create directory!");
			}
		}
	}
	
	public void deleteSubject(String subject) {
		File file = new File(dir + "/" + checkSymbols(subject)
				+ ".fach");
		if (file.exists()) {
			file.delete();
			System.out.println("File " + dir + "/" + checkSymbols(subject) + ".fach deleted");
		} else {
			System.out.println("File " + dir + "/" + checkSymbols(subject) + ".fach not found");
		}
	}

	// Check the String for unsupported Symbols
	public String checkSymbols(String toTest) {
		String finalString = toTest;
		finalString.replaceAll("\u00e4", "ae");
		finalString.replaceAll("\u00f6", "oe");
		finalString.replaceAll("\u00fc", "ue");
		finalString.replaceAll("\130", "e");
		finalString.replaceAll("\138", "e");
		finalString.replaceAll("\156", "oe");
		//System.out.println("Changed " + toTest + " to " + finalString);
		return finalString;
	}
	
	public String[] getProfileNames() {
		File folder = new File(dir);
		File[] listOfFiles = folder.listFiles();
		String[] listOfFileNames = new String[listOfFiles.length];
		ArrayList<String> profileNames = new ArrayList(); 
		
		for (File file : listOfFiles) {
		    if (file.isFile()) {
		        //System.out.println(file.getName());
		        if(file.getName().endsWith(".profile")){
		        	profileNames.add(file.getName().replaceAll(".profile", ""));
		        }
		    }
		}
		String[] profileNamesArray = new String[profileNames.size()];
		for(int i = 0; i < profileNames.size(); i++) {
			//System.out.println(profileNames.get(i));
			profileNamesArray[i] = profileNames.get(i);
		}
		return profileNamesArray;
	}
}
